package com.example.spider.proxy.provider.ip89;

import cn.hutool.core.util.ReUtil;
import com.example.spider.proxy.core.ProxyInfo;
import com.example.spider.proxy.core.tester.ProxyTypeEnum;
import com.example.spider.proxy.provider.AbstractProxyResultHandler;
import com.example.spider.proxy.provider.IpProxySpiderTask;
import com.example.spider.starter.SpiderStarter;
import com.example.spider.task.SpiderTaskQueue;
import lombok.extern.slf4j.Slf4j;
import org.shoulder.core.converter.LocalDateTimeConverter;

import java.time.Duration;
import java.util.List;

/**
 * https://www.89ip.cn/index_1.html
 * 可用性代理不到10%，每页18项，页数不固定，会波动，需要根据返回值长度来决定是否爬下一页，大概50页左右
 * https://www.89ip.cn/tqdl.html?num=9999 一次返回
 *
 * @author lym
 */
@Slf4j
//@Component
public class Ip89DetailResultHandler extends AbstractProxyResultHandler implements SpiderStarter {

    public Ip89DetailResultHandler() {
        super("ip89");
    }

    protected Duration defaultLimitRateDuration() {
        return Duration.ofSeconds(3);
    }

    @Override
    public void startSpiders() {
        //IpProxySpiderTask task = createTask("https://www.89ip.cn/index_1.html/");
        IpProxySpiderTask task = createTask("https://www.89ip.cn/tqdl.html?num=3747");
        SpiderTaskQueue.putTask(task);
    }

    @Override
    public String executeCron() {
        return "0 0/50 * * * ?";
    }

    @Override
    protected void doHandle(IpProxySpiderTask task, String html) {
        if (task.getUrl().contains("www.89ip.cn/tqdl.html?")) {
            parseFromIpPortLine(html);

        } else {
            parseFromHtml(task, html);
        }
    }

    private void parseFromIpPortLine(String html) {
        String content = html.split("<hr/>")[1];
        List<String> ipAndPort = ReUtil.findAll(">(\\d+\\.\\d+\\.\\d+\\.\\d+:\\d{1,5})", content, 1);
        ipAndPort.parallelStream().forEach(ipPortStr -> {
            String[] ipPort = ipPortStr.split(":");
            ProxyInfo proxyInfo = ProxyInfo.builder()
                    .source(taskName)
                    .ip(ipPort[0])
                    .port(Integer.parseInt(ipPort[1]))
                    .proxyTypeEnum(ProxyTypeEnum.UNKNOWN)
                    .type(ProxyTypeEnum.UNKNOWN.getType())
                    .build();
            addProxyToSourceRepository(proxyInfo);
        });
    }

    protected void parseFromHtml(IpProxySpiderTask task, String html) {
        // 要解析的太多了，先截取期望部分，避免每次解析全部html
        String tableRegex = "<tbody>(.*?)</tbody>";
        List<String> contentStr = ReUtil.findAllGroup1(tableRegex, html);
        if (contentStr.isEmpty()) {
            // 结束了
            log.error("ip89Detail invalid. Task:{}", task);
            return;
        }

        String table = contentStr.get(0);

        String ipRegex = "<tr>.*?<td>(.*?)</td>" +
                ".*?<td>(.*?)</td>" +
                ".*?<td>(.*?)</td>" +
                ".*?<td>(.*?)</td>" +
                ".*?<td>(.*?)</td>";

        List<String> ipList = ReUtil.findAllGroup1(ipRegex, table);
        List<String> portList = ReUtil.findAll(ipRegex, table, 2);
        List<String> locationList = ReUtil.findAll(ipRegex, table, 3);
        List<String> operatorList = ReUtil.findAll(ipRegex, table, 4);
        List<String> lastVerificationTimeList = ReUtil.findAll(ipRegex, table, 5);

        for (int i = 0; i < ipList.size(); i++) {
            ProxyInfo proxyInfo = ProxyInfo.builder()
                    .source(taskName)
                    .ip(ipList.get(i).strip())
                    .port(Integer.parseInt(portList.get(i).strip()))
                    .location(locationList.get(i).strip())
                    .operator(operatorList.get(i).strip())
                    .lastVerificationTime(LocalDateTimeConverter.INSTANCE.convert(lastVerificationTimeList.get(i)))
                    .build();
            addProxyToSourceRepository(proxyInfo);
        }

        // 下一页
        if (ipList.size() > 5) {
            String currentPageStr = ReUtil.findAllGroup1("https://www.89ip.cn/index_(\\d+).html/", task.getUrl()).get(0);
            int currentPageNum = Integer.parseInt(currentPageStr);
            int nextPageNum = currentPageNum + 1;
            IpProxySpiderTask nextPageTask = createTask("https://www.89ip.cn/index_" + nextPageNum + ".html/");
            SpiderTaskQueue.putTask(nextPageTask);
        }
    }

}
